﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.Xml;
using System.IO;

namespace UMLDraw
{
    public partial class MainForm : Form
    {
        public static WorkPlace WPlace = new WorkPlace();
        public static Input IPut = new Input();
        public static Output OPut = new Output();
        public static List<State> STate = new List<State>();
        public static List<Transfer> TFer = new List<Transfer>();
        public static List<Comment> CMent = new List<Comment>();
        public static List<SerilizeData> History = new List<SerilizeData>();
        public static int RealTime;
        public bool isSaved;

        OpenFileDialog openFileDialog1 = new OpenFileDialog();      
        SaveFileDialog saveFileDialog1 = new SaveFileDialog();  
  
        SerilizeData DATA = new SerilizeData();

        public MainForm()
        {
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            InitializeComponent();
            InitializeOpenFileDialog();
            InitializeSaveFileDialog();
            SetStartStatus();
        }
        //                                                  //
        // *****Управление свойствами рабочего поля*****    //
        //                                                  //
        private void SetStartStatus()
        {
            WPlace.path = "";
            tPStructure.Enabled = false;
            правкаToolStripMenuItem.Enabled = false;
            tSBSave.Enabled = false;
            tSBIn.Enabled = false;
            tSBOut.Enabled = false;
            tSBState.Enabled = false;
            tSBTransfer.Enabled = false;
            tSBComment.Enabled = false;
            trbScrol.Enabled = false;
            tSBRedo.Enabled = false;
            tSBUndo.Enabled = false;
            tSBSaveAsImage.Enabled = false;
            trbScrol.Hide();
            label1.Hide();
            setupSize(0,0);
            tPStructure.Select();
        }
        private void SetWorkStatus()
        {
            tPStructure.Enabled = true;
            правкаToolStripMenuItem.Enabled = true;
            tSBSave.Enabled = true;
            tSBIn.Enabled = true;
            tSBOut.Enabled = true;
            tSBState.Enabled = true;
            tSBTransfer.Enabled = true;
            tSBComment.Enabled = true;
            trbScrol.Enabled = true;
            tSBRedo.Enabled = true;
            tSBUndo.Enabled = true;
            tSBSaveAsImage.Enabled = true;
            isSaved = true;
            trbScrol.Show();
            label1.Show();
            trbScrol.Value = 5;
            setupSize(WPlace.WorkPlaceWidht, WPlace.WorkPlaceHeight);

            if (History.Count == 0)
            {
                SerilizeData hisBuff = new SerilizeData();
                conversionData(hisBuff);
                History.Add(hisBuff);
                RealTime = 0;
            }
        }
        private void InitializeOpenFileDialog()
        {
            this.openFileDialog1.Title = "Открыть";
            this.openFileDialog1.Filter = "All files (*.*)|*.*";
            this.openFileDialog1.Multiselect = false;
            this.saveFileDialog1.InitialDirectory = "C:\\";
        }
        private void InitializeSaveFileDialog()
        {
            this.saveFileDialog1.Title = "Сохранить";
            this.saveFileDialog1.Filter = "All files|*.*";
            this.saveFileDialog1.InitialDirectory = "C:\\";
        }
        private void setupSize(int X, int Y)
        {
            this.canvas.Height = Y;
            this.canvas.Width = X;
        }

        //                                                                  //
        // *****добавление и редактирование элементов рабочего поля*****    //
        //                                                                  //
        //обработчик добавления элемента
        private void panel2_ClickOn(object sender, MouseEventArgs e)
        {
            canvas.Focus();
            UMLDraw.MainForm.WPlace.selectSth("WP");
            switch (WPlace.CurrentAction)
            {
                case "SelectItem":
                    break;
                case "AddInput":
                    if(Controls.Find("Input", true).Count() == 0)
                    {
                        IPut = new Input();
                        WPlace.tree.Nodes.Add(IPut.Node);
                        tPStructure.Nodes.Clear();
                        tPStructure.Nodes.Add(WPlace.tree);
                        IPut.Initialize(canvas, e.X, e.Y);
                        this.Refresh();
                        IPut.Image.Show();
                        NewHistoryRec();
                    }
                    else
                    {
                        MessageBox.Show("Нельзя создать больше одной точки входа");
                    }
                    WPlace.CurrentAction = "SelectItem";
                    break;
                case "AddOutput":
                    if(Controls.Find("Output", true).Count() == 0)
                    {
                        OPut = new Output();
                        WPlace.tree.Nodes.Add(OPut.Node);
                        tPStructure.Nodes.Clear();
                        tPStructure.Nodes.Add(WPlace.tree);
                        OPut.Initialize(canvas, e.X, e.Y);
                        this.Refresh();
                        NewHistoryRec();
                    }
                    else
                    {
                        MessageBox.Show("Нельзя создать больше одной точки выхода");
                    }
                    WPlace.CurrentAction = "SelectItem";
                    break;
                case "AddState":
                    State sBuff = new State();          //создаём экземпляр объекта State
                    AppendToWorkPlace(e, sBuff);        //добавляем экземпляр объекта State к классу WorkPlace
                    STate.Add(sBuff);                   //добавляем экземпляр объекта State к листу State
                    WPlace.CurrentAction = "SelectItem";
                    NewHistoryRec();
                    break;
                case "AddTransfer":
                    break;
                case "AddComment":
                    Comment cBuff = new Comment();      //создаём экземпляр объекта Сomment
                    AppendToWorkPlace(e, cBuff);        //добавляем экземпляр объекта Сomment к классу WorkPlace 
                    CMent.Add(cBuff);                   //добавляем экземпляр объекта Сomment к листу Comment
                    WPlace.CurrentAction = "SelectItem";
                    NewHistoryRec();
                    break;
            }

        }
        //добавление элемента на рабочее поле(на форму и в лист класса)
        private void AppendToWorkPlace(MouseEventArgs e, State sBuff)
        {
            sBuff.Initialize(sBuff.Name += WPlace.ActualState, sBuff.Text += WPlace.ActualState, canvas, e.X, e.Y, sBuff.Entry, sBuff.Do, sBuff.Exit, sBuff.Style);
            WPlace.ActualState++;
            WPlace.tree.Nodes.Add(sBuff.Node);
            tPStructure.Nodes.Clear();
            tPStructure.Nodes.Add(WPlace.tree);
        }
        private void AppendToWorkPlace(MouseEventArgs e, Comment cBuff)
        {
            cBuff.Initialize(cBuff.Name += WPlace.ActualComment, cBuff.Text += WPlace.ActualComment, canvas, e.X, e.Y);
            WPlace.ActualComment++;
            WPlace.tree.Nodes.Add(cBuff.Node);
            tPStructure.Nodes.Clear();
            tPStructure.Nodes.Add(WPlace.tree);
        }
        private void AppendToWorkPlace(Transfer tBuff)
        {
            canvas.Focus();
            tBuff.Initialize(tBuff.Name += WPlace.ActualTransfer, tBuff.Text += WPlace.ActualTransfer, "Unknown", "Unknown", panel3, shapeContainer1);
            WPlace.ActualTransfer++;
            WPlace.tree.Nodes.Add(tBuff.Node);
        }
        //Удаление рабочего поля
        private void removeWorkPlace()
        {
            while (WPlace.tree.Nodes.Count > 0)
                removeControl(WPlace.tree.FirstNode.Name);
            WPlace.tree.Nodes.Clear();
            tPStructure.Nodes.Clear();
            WPlace.ActualComment = 0;
            CMent.Clear();
            WPlace.ActualState = 0;
            STate.Clear();
            WPlace.ActualTransfer = 0;
            TFer.Clear();
            IPut.isLocated = false;
            OPut.isLocated = false;
            SetStartStatus();
        }
        //Удаление выбранного контрола с рабочего поля
        private void removeControl(string key)
        {
            if (key.Contains("Transfer"))
            {
                TFer[Convert.ToInt16(key.Replace("Transfer", ""))].Line.Dispose();
                TFer[Convert.ToInt16(key.Replace("Transfer", ""))].Names.Dispose();
                TFer[Convert.ToInt16(key.Replace("Transfer", ""))].LNames.Dispose();
                TFer[Convert.ToInt16(key.Replace("Transfer", ""))].specLine.Dispose();
            }

            if (key.Contains("State"))
            {
                STate[Convert.ToInt16(key.Replace("State", ""))].Image.Dispose();
                STate[Convert.ToInt16(key.Replace("State", ""))].Names.Dispose();
                STate[Convert.ToInt16(key.Replace("State", ""))].Entrys.Dispose();
                STate[Convert.ToInt16(key.Replace("State", ""))].Dos.Dispose();
                STate[Convert.ToInt16(key.Replace("State", ""))].Exits.Dispose();
                for (int i = 0; i < 4; i++)
                    STate[Convert.ToInt16(key.Replace("State", ""))].Marks[i].Dispose();
                for (int i = 0; i < STate[Convert.ToInt16(key.Replace("State", ""))].InputName.Count(); i++)
                {
                    try
                    {
                        TFer[Convert.ToInt16(STate[Convert.ToInt16(key.Replace("State", ""))].InputName[i].Replace("Transfer", ""))].Line.Dispose();
                        TFer[Convert.ToInt16(STate[Convert.ToInt16(key.Replace("State", ""))].InputName[i].Replace("Transfer", ""))].Names.Dispose();
                        TFer[Convert.ToInt16(STate[Convert.ToInt16(key.Replace("State", ""))].InputName[i].Replace("Transfer", ""))].LNames.Dispose();
                        TFer[Convert.ToInt16(STate[Convert.ToInt16(key.Replace("State", ""))].InputName[i].Replace("Transfer", ""))].specLine.Dispose();
                        WPlace.tree.Nodes[STate[Convert.ToInt16(key.Replace("State", ""))].InputName[i]].Remove();
                    }
                    catch { }
                }
                for (int i = 0; i < STate[Convert.ToInt16(key.Replace("State", ""))].OutputName.Count(); i++)
                {
                    try
                    {
                        TFer[Convert.ToInt16(STate[Convert.ToInt16(key.Replace("State", ""))].OutputName[i].Replace("Transfer", ""))].Line.Dispose();
                        TFer[Convert.ToInt16(STate[Convert.ToInt16(key.Replace("State", ""))].OutputName[i].Replace("Transfer", ""))].Names.Dispose();
                        TFer[Convert.ToInt16(STate[Convert.ToInt16(key.Replace("State", ""))].OutputName[i].Replace("Transfer", ""))].LNames.Dispose();
                        TFer[Convert.ToInt16(STate[Convert.ToInt16(key.Replace("State", ""))].OutputName[i].Replace("Transfer", ""))].specLine.Dispose();
                        WPlace.tree.Nodes[STate[Convert.ToInt16(key.Replace("State", ""))].OutputName[i]].Remove();
                    }
                    catch { }
                }      
            }
            if (key.Contains("Comment"))
            {
                CMent[Convert.ToInt16(key.Replace("Comment", ""))].Image.Dispose();
                CMent[Convert.ToInt16(key.Replace("Comment", ""))].Names.Dispose();
                for (int i = 0; i < 4; i++)
                    CMent[Convert.ToInt16(key.Replace("Comment", ""))].Marks[i].Dispose();
                for (int i = 0; i < CMent[Convert.ToInt16(key.Replace("Comment", ""))].InputName.Count(); i++)
                {
                    try
                    {
                        TFer[Convert.ToInt16(CMent[Convert.ToInt16(key.Replace("Comment", ""))].InputName[i].Replace("Transfer", ""))].Line.Dispose();
                        TFer[Convert.ToInt16(CMent[Convert.ToInt16(key.Replace("Comment", ""))].InputName[i].Replace("Transfer", ""))].Names.Dispose();
                        TFer[Convert.ToInt16(CMent[Convert.ToInt16(key.Replace("Comment", ""))].InputName[i].Replace("Transfer", ""))].LNames.Dispose();
                        TFer[Convert.ToInt16(CMent[Convert.ToInt16(key.Replace("Comment", ""))].InputName[i].Replace("Transfer", ""))].specLine.Dispose();
                        WPlace.tree.Nodes[CMent[Convert.ToInt16(key.Replace("Comment", ""))].InputName[i]].Remove();
                    }
                    catch { }
                }
                for (int i = 0; i < CMent[Convert.ToInt16(key.Replace("Comment", ""))].OutputName.Count(); i++)
                {
                    try
                    {
                        TFer[Convert.ToInt16(CMent[Convert.ToInt16(key.Replace("Comment", ""))].OutputName[i].Replace("Transfer", ""))].Line.Dispose();
                        TFer[Convert.ToInt16(CMent[Convert.ToInt16(key.Replace("Comment", ""))].OutputName[i].Replace("Transfer", ""))].Names.Dispose();
                        TFer[Convert.ToInt16(CMent[Convert.ToInt16(key.Replace("Comment", ""))].OutputName[i].Replace("Transfer", ""))].LNames.Dispose();
                        TFer[Convert.ToInt16(CMent[Convert.ToInt16(key.Replace("Comment", ""))].OutputName[i].Replace("Transfer", ""))].specLine.Dispose();
                        WPlace.tree.Nodes[CMent[Convert.ToInt16(key.Replace("Comment", ""))].OutputName[i]].Remove();
                    }
                    catch { }
                }
            }
            if (key.Contains("Input"))
            {
                IPut.Image.Dispose();
                IPut.isLocated = false;
                for (int i = 0; i < 4; i++)
                    IPut.Marks[i].Dispose();
                for (int i = 0; i < IPut.OutputName.Count(); i++)
                {
                    try
                    {
                        TFer[Convert.ToInt16(IPut.OutputName[i].Replace("Transfer", ""))].Line.Dispose();
                        TFer[Convert.ToInt16(IPut.OutputName[i].Replace("Transfer", ""))].Names.Dispose();
                        TFer[Convert.ToInt16(IPut.OutputName[i].Replace("Transfer", ""))].LNames.Dispose();
                        TFer[Convert.ToInt16(IPut.OutputName[i].Replace("Transfer", ""))].specLine.Dispose();
                        WPlace.tree.Nodes[IPut.OutputName[i]].Remove();
                    }
                    catch { }
                }
            }
            if (key.Contains("Output"))
            {
                OPut.Image.Dispose();
                OPut.isLocated = false;
                for (int i = 0; i < 4; i++)
                    OPut.Marks[i].Dispose();
                for (int i = 0; i < OPut.InputName.Count(); i++)
                {
                    try
                    {
                        TFer[Convert.ToInt16(OPut.InputName[i].Replace("Transfer", ""))].Line.Dispose();
                        TFer[Convert.ToInt16(OPut.InputName[i].Replace("Transfer", ""))].Names.Dispose();
                        TFer[Convert.ToInt16(OPut.InputName[i].Replace("Transfer", ""))].LNames.Dispose();
                        TFer[Convert.ToInt16(OPut.InputName[i].Replace("Transfer", ""))].specLine.Dispose();
                        WPlace.tree.Nodes[OPut.InputName[i]].Remove();
                    }
                    catch { }
                }
            }
            WPlace.tree.Nodes[key].Remove();
        }
        //Удаление выбранного элемента
        private void tPStructure_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            int count = tPStructure.GetNodeCount(true);
            if (tPStructure.SelectedNode != null)
            {
                if (e.KeyValue == 46) 
                {
                    string name = tPStructure.SelectedNode.Name;
                    if (name.Contains("Рабочее поле"))
                        removeWorkPlace();
                    else
                        removeControl(name);
                }
            }
        }
        //сброс текущей операции добавления елемента
        private void panel2_Leave(object sender, EventArgs e)
        {
            WPlace.CurrentAction = "SelectItem";
        }
        //                                                                  //
        // *****вызовы элементов текстового меню и панели инструментов***** //
        //                                                                  //
        //добавление элемента вход
        private void tSBIn_Click(object sender, EventArgs e)
        {
            WPlace.CurrentAction = "AddInput";
        }
        private void входToolStripMenuItem_Click(object sender, EventArgs e)
        {
            WPlace.CurrentAction = "AddInput";
        }
        //добавление элемента состояние
        private void tSBState_Click(object sender, EventArgs e)
        {
            WPlace.CurrentAction = "AddState";
        }
        private void состояниеToolStripMenuItem_Click(object sender, EventArgs e)
        {
            WPlace.CurrentAction = "AddState";
        }
        //добавление элемента переход
        private void tSBTransfer_Click(object sender, EventArgs e)
        {
            WPlace.CurrentAction = "AddTransfer";
            Transfer tBuff = new Transfer();
            AppendToWorkPlace(tBuff);
            TFer.Add(tBuff);
        }
        private void переходToolStripMenuItem_Click(object sender, EventArgs e)
        {
            WPlace.CurrentAction = "AddTransfer";
            Transfer tBuff = new Transfer();
            AppendToWorkPlace(tBuff);
            TFer.Add(tBuff);
        }
        //добавление элемента выход
        private void tSBOut_Click(object sender, EventArgs e)
        {
            WPlace.CurrentAction = "AddOutput";
        }
        private void выходToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            WPlace.CurrentAction = "AddOutput";
        }
        //добавление элемента комментарий
        private void tSBComment_Click(object sender, EventArgs e)
        {
            WPlace.CurrentAction = "AddComment";
        }
        private void комментарийToolStripMenuItem_Click(object sender, EventArgs e)
        {
            WPlace.CurrentAction = "AddComment";
        }
        //создание нового проекта
        private void tSBNew_Click(object sender, EventArgs e)
        {
            if (WPlace.tree.Nodes.Count > 0 && isSaved == true)
            {
                var result = MessageBox.Show("Хотите сохранить текущий проект?", "Автосохранение", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                if (result == DialogResult.Yes)
                    if (WPlace.path == "")
                        saveAs();
                    else
                        try
                        {
                            save();
                        }
                        catch
                        {
                            saveAs();
                        }
                if (result == DialogResult.Cancel)
                    return;
            }
            removeWorkPlace();
            tPStructure.Nodes.Add(WPlace.tree);
            History.Clear();
            SetWorkStatus();
        }
        private void новыйПроектToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (WPlace.tree.Nodes.Count > 0 && isSaved == true)
            {
                var result = MessageBox.Show("Хотите сохранить текущий проект?", "Автосохранение", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                if (result == DialogResult.Yes)
                    if (WPlace.path == "")
                        saveAs();
                    else
                        try
                        {
                            save();
                        }
                        catch
                        {
                            saveAs();
                        }
                if (result == DialogResult.Cancel)
                    return;
            }
            removeWorkPlace();
            tPStructure.Nodes.Add(WPlace.tree);
            History.Clear();
            SetWorkStatus();
        }
        //изменение размера рабочего поля
        private void размерРабочегоПоляToolStripMenuItem_Click(object sender, EventArgs e)
        {
            WorkPlaceSize dialog = new WorkPlaceSize();
            DialogResult result = dialog.ShowDialog();
            setupSize(WPlace.WorkPlaceWidht, WPlace.WorkPlaceHeight);
            NewHistoryRec();
        }
        //выход из программы
        private void выходToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        //вывод информации о программе
        private void оПрограммеToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutProgram dialog = new AboutProgram();
            DialogResult resulr = dialog.ShowDialog();
        }
        //вывод справки
        private void tSBHelp_Click(object sender, EventArgs e)
        {
            Help dialog = new Help();
            dialog.Show();
        }
        private void помощьПользователюToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Help dialog = new Help();
            dialog.Show();
        }
        //преобразование данных для серилизации
        private void conversionData(SerilizeData savedData)
        {
            savedData.WP.Save(WPlace.Name, WPlace.ActualState, WPlace.ActualTransfer, WPlace.ActualComment, WPlace.WorkPlaceWidht, WPlace.WorkPlaceHeight);
            savedData.IN.Save(IPut.XCoor, IPut.YCoor, IPut.OutputName, IPut.isLocated);
            savedData.OU.Save(OPut.XCoor, OPut.YCoor, OPut.InputName, OPut.isLocated);
            savedData.ST.Clear();
            for (int i = 0; i < STate.Count(); i++)
            {
                SerilizeData.STData sbuff = new SerilizeData.STData();
                sbuff.Save(STate[i].Name, STate[i].Text, STate[i].XCoor, STate[i].YCoor, STate[i].InputName, STate[i].OutputName, STate[i].Entry, STate[i].Do, STate[i].Exit, STate[i].Style);
                savedData.ST.Add(sbuff);
            }
            savedData.CO.Clear();
            for (int i = 0; i < CMent.Count(); i++)
            {
                SerilizeData.COData cbuff = new SerilizeData.COData();
                cbuff.Save(CMent[i].Name, CMent[i].Text, CMent[i].XCoor, CMent[i].YCoor, CMent[i].InputName, CMent[i].OutputName);
                savedData.CO.Add(cbuff);
            }
            savedData.TR.Clear();
            for (int i = 0; i < TFer.Count(); i++)
            {
                SerilizeData.TRData tbuff = new SerilizeData.TRData();
                tbuff.Save(TFer[i].Name, TFer[i].Node.Text, TFer[i].FromName, TFer[i].ToName);
                savedData.TR.Add(tbuff);
            }
        }
        //сохранение проекта
        private void tSBSave_Click(object sender, EventArgs e)
        {
            if (WPlace.path == "")
                saveAs();
            else
                try
                {
                    save();
                }
                catch
                {
                    saveAs();
                }
        }
        private void сохранитьПроектToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (WPlace.path == "")
                saveAs();
            else
                try
                {
                    save();
                }
                catch
                {
                    saveAs();
                }
        }
        private void save()
        {
            conversionData(DATA);
            XmlSerializer s = new XmlSerializer(typeof(SerilizeData));
            TextWriter w = new StreamWriter(WPlace.path);
            DATA.WP.Name = WPlace.path.Remove(WPlace.path.LastIndexOf(".")).Remove(0, WPlace.path.LastIndexOf("\\") + 1);
            WPlace.Name = WPlace.path.Remove(WPlace.path.LastIndexOf(".")).Remove(0, WPlace.path.LastIndexOf("\\") + 1);
            WPlace.tree.Text = WPlace.path.Remove(WPlace.path.LastIndexOf(".")).Remove(0, WPlace.path.LastIndexOf("\\") + 1);
            s.Serialize(w, DATA);
            w.Flush();
            w.Close();
            isSaved = true;
        }
        private void сохранитьПроектКакToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveAs();
        }
        private void saveAs()
        {
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    conversionData(DATA);
                    XmlSerializer s = new XmlSerializer(typeof(SerilizeData));
                    TextWriter w = new StreamWriter(saveFileDialog1.FileName);
                    DATA.WP.Name = saveFileDialog1.FileName.Remove(saveFileDialog1.FileName.LastIndexOf(".")).Remove(0, saveFileDialog1.FileName.LastIndexOf("\\") + 1);
                    WPlace.Name = saveFileDialog1.FileName.Remove(saveFileDialog1.FileName.LastIndexOf(".")).Remove(0, saveFileDialog1.FileName.LastIndexOf("\\") + 1);
                    WPlace.tree.Text = saveFileDialog1.FileName.Remove(saveFileDialog1.FileName.LastIndexOf(".")).Remove(0, saveFileDialog1.FileName.LastIndexOf("\\") + 1);
                    s.Serialize(w, DATA);
                    w.Flush();
                    w.Close();
                    WPlace.path = saveFileDialog1.FileName;
                    //MessageBox.Show("Объект успешно сериализован в файл" + saveFileDialog1.FileName, "Операция выполнена", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    isSaved = true;
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
        //преобразование данных после серилизации
        private void deConversionData(SerilizeData savedData)
        {
            WPlace.Initialize(savedData.WP.Name, savedData.WP.ActualState, savedData.WP.ActualTransfer, savedData.WP.ActualComment, savedData.WP.WorkPlaceWidht, savedData.WP.WorkPlaceHeight);
            SetWorkStatus();
            for (int i = 0; i < savedData.TR.Count(); i++)
            {
                Transfer tBuff = new Transfer();
                tBuff.Initialize(savedData.TR[i].Name, savedData.TR[i].Text, savedData.TR[i].FromName, savedData.TR[i].ToName, panel3, shapeContainer1);
                WPlace.tree.Nodes.Add(tBuff.Node);
                tPStructure.Nodes.Clear();
                tPStructure.Nodes.Add(WPlace.tree);
                TFer.Add(tBuff);
            }
            if (savedData.IN.isLocated == true)
            {
                IPut = new Input();
                WPlace.tree.Nodes.Add(IPut.Node);
                tPStructure.Nodes.Clear();
                tPStructure.Nodes.Add(WPlace.tree);
                IPut.Initialize(canvas, savedData.IN.XCoor, savedData.IN.YCoor);
                IPut.OutputName = savedData.IN.OutputName;
            }
            if (savedData.OU.isLocated == true)
            {
                OPut = new Output();
                WPlace.tree.Nodes.Add(OPut.Node);
                tPStructure.Nodes.Clear();
                tPStructure.Nodes.Add(WPlace.tree);
                OPut.Initialize(canvas, savedData.OU.XCoor, savedData.OU.YCoor);
                OPut.InputName = savedData.OU.InputName;
            }

            for (int i = 0; i < savedData.ST.Count(); i++)
            {
                State sBuff = new State();
                sBuff.Initialize(savedData.ST[i].Name, savedData.ST[i].Text, canvas, savedData.ST[i].XCoor, savedData.ST[i].YCoor, savedData.ST[i].Entry, savedData.ST[i].Do, savedData.ST[i].Exit, savedData.ST[i].Style);
                sBuff.InputName = savedData.ST[i].InputName;
                sBuff.OutputName = savedData.ST[i].OutputName;
                WPlace.tree.Nodes.Add(sBuff.Node);
                tPStructure.Nodes.Clear();
                tPStructure.Nodes.Add(WPlace.tree);
                STate.Add(sBuff);  
            }

            for (int i = 0; i < savedData.CO.Count(); i++)
            {
                Comment cBuff = new Comment();
                cBuff.Initialize(savedData.CO[i].Name, savedData.CO[i].Text, canvas, savedData.CO[i].XCoor, savedData.CO[i].YCoor);
                cBuff.InputName = savedData.CO[i].InputName;
                cBuff.OutputName = savedData.CO[i].OutputName;
                cBuff.Image.Refresh();
                WPlace.tree.Nodes.Add(cBuff.Node);
                tPStructure.Nodes.Clear();
                tPStructure.Nodes.Add(WPlace.tree);
                CMent.Add(cBuff);      
            }

            for (int i = 0; i < STate.Count(); i++)
            {
                STate[i].RewriteTransfer(STate[i].Image as Control);
            }
            for (int i = 0; i < CMent.Count(); i++)
            {
                CMent[i].RewriteTransfer(CMent[i].Image as Control);
            }

            //canvas.Refresh();
        }
        //открытие проекта
        private void tSBOpen_Click(object sender, EventArgs e)
        {
            load();
        }
        private void открытьПроектToolStripMenuItem_Click(object sender, EventArgs e)
        {
            load();
        }
        private void load()
        {
            if (WPlace.tree.Nodes.Count > 0 && isSaved == false)
            {
                var result = MessageBox.Show("Хотите сохранить текущий проект?", "Автосохранение", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                if (result == DialogResult.Yes)
                    if (WPlace.path == "")
                        saveAs();
                    else
                        try
                        {
                            save();
                        }
                        catch
                        {
                            saveAs();
                        }
                if (result == DialogResult.Cancel)
                    return;
            }

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    //Попробуем десериализовать файл serializeExample.xml в корне диска C
                    XmlSerializer s = new XmlSerializer(typeof(SerilizeData));
                    TextReader r = new StreamReader(openFileDialog1.FileName);
                    DATA = (SerilizeData)s.Deserialize(r);
                    r.Close();
                    //MessageBox.Show("Объект успешно десериализован из файла" + openFileDialog1.FileName, "Операция выполнена", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    //очищаем рабочее поле
                    removeWorkPlace();
                    tPStructure.Nodes.Add(WPlace.tree);
                    History.Clear();
                    //обновдяем контролы
                    deConversionData(DATA);
                    NewHistoryRec();
                    WPlace.path = openFileDialog1.FileName;
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
        //изменение масштаба рабочего поля
        private int previusValue = 5;
        private bool isSthSelected = false;
        private void changeScale(object sender, EventArgs e)
        {
            System.Drawing.SizeF Scale = System.Drawing.SizeF.Empty;
            if (trbScrol.Value > previusValue)
            {
                WPlace.Scale *= 1.2;
                Scale.Width = 1.2F;
                Scale.Height =1.2F;
            }
            if (trbScrol.Value < previusValue)
            {
                WPlace.Scale /= 1.2;
                Scale.Width = 1 / 1.2F;
                Scale.Height = 1 / 1.2F;
            }

            for (int i = 0; i < STate.Count(); i++)
            {
                if (STate[i].isSelected)
                {
                    STate[i].Scale = WPlace.Scale;
                    STate[i].Image.Scale(Scale);
                    STate[i].Names.Scale(Scale);
                    STate[i].Entrys.Scale(Scale);
                    STate[i].Dos.Scale(Scale);
                    STate[i].Exits.Scale(Scale);
                    STate[i].setPerimeterPoints(STate[i].Image.Location.X, STate[i].Image.Location.Y);
                    for (int j = 0; j < 4; j++)
                        STate[i].Marks[j].Location = STate[i].PerimeterPoint[j];
                    isSthSelected = true;
                }
            }
            for (int i = 0; i < CMent.Count(); i++)
            {
                if (CMent[i].isSelected)
                {
                    CMent[i].Scale = WPlace.Scale;
                    CMent[i].Names.Scale(Scale);
                    CMent[i].Image.Scale(Scale);
                    CMent[i].setPerimeterPoints(CMent[i].Image.Location.X, CMent[i].Image.Location.Y);
                    for (int j = 0; j < 4; j++)
                        CMent[i].Marks[j].Location = CMent[i].PerimeterPoint[j];
                    isSthSelected = true;
                }
            }

            if(IPut.isSelected)
            {
                IPut.Image.Scale(Scale);
                IPut.setPerimeterPoints(IPut.Image.Location.X, IPut.Image.Location.Y);
                for (int j = 0; j < 4; j++)
                    IPut.Marks[j].Location = IPut.PerimeterPoint[j];
                isSthSelected = true;
            }
            if (OPut.isSelected)
            {
                OPut.Image.Scale(Scale);
                OPut.setPerimeterPoints(OPut.Image.Location.X, OPut.Image.Location.Y);
                for (int j = 0; j < 4; j++)
                    OPut.Marks[j].Location = OPut.PerimeterPoint[j];
                isSthSelected = true;
            }

            if (!isSthSelected)
            {
                for (int i = 0; i < STate.Count(); i++)
                {
                    STate[i].Scale = WPlace.Scale;
                    STate[i].Image.Scale(Scale);
                    STate[i].Names.Scale(Scale);
                    STate[i].Entrys.Scale(Scale);
                    STate[i].Dos.Scale(Scale);
                    STate[i].Exits.Scale(Scale);
                    STate[i].setPerimeterPoints(STate[i].Image.Location.X, STate[i].Image.Location.Y);
                }
                for (int i = 0; i < CMent.Count(); i++)
                {
                    CMent[i].Scale = WPlace.Scale;
                    CMent[i].Names.Scale(Scale);
                    CMent[i].Image.Scale(Scale);
                    CMent[i].setPerimeterPoints(CMent[i].Image.Location.X, CMent[i].Image.Location.Y);
                }
                IPut.Image.Scale(Scale);
                IPut.setPerimeterPoints(IPut.Image.Location.X, IPut.Image.Location.Y);
                OPut.Image.Scale(Scale);
                OPut.setPerimeterPoints(OPut.Image.Location.X, OPut.Image.Location.Y);
            }

            for (int i = 0; i < STate.Count(); i++)
            {
                STate[i].RewriteTransfer(STate[i].Image as Control);
            }
            for (int i = 0; i < CMent.Count(); i++)
            {
                CMent[i].RewriteTransfer(CMent[i].Image as Control);
            }
            previusValue = trbScrol.Value;
            isSthSelected = false;
        }

        private void MainForm_FormClosed(object sender, FormClosingEventArgs e)
        {
            if (WPlace.tree.Nodes.Count > 0 && isSaved == false)
            {
                var result = MessageBox.Show("Хотите сохранить текущий проект?", "Автосохранение", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                if (result == DialogResult.Yes)
                    if (WPlace.path == "")
                        saveAs();
                    else
                        try
                        {
                            save();
                        }
                        catch
                        {
                            saveAs();
                        }
                if (result == DialogResult.Cancel)
                    e.Cancel = true;
            }
        }

        private void tSBUndo_Click(object sender, EventArgs e)
        {
            if (RealTime > 0)
            {
                RealTime--;
                removeWorkPlace();
                tPStructure.Nodes.Add(WPlace.tree);
                deConversionData(History[RealTime]);
                isSaved = false;
            }
        }

        private void отменитьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (RealTime > 0)
            {
                RealTime--;
                removeWorkPlace();
                tPStructure.Nodes.Add(WPlace.tree);
                deConversionData(History[RealTime]);
                isSaved = false;
            }
        }

        private void tSBRedo_Click(object sender, EventArgs e)
        {
            if (RealTime < History.Count - 1)
            {
                RealTime++;
                removeWorkPlace();
                tPStructure.Nodes.Add(WPlace.tree);
                deConversionData(History[RealTime]);
                isSaved = false;
            }
        }

        private void вернутьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (RealTime < History.Count - 1)
            {
                RealTime++;
                removeWorkPlace();
                tPStructure.Nodes.Add(WPlace.tree);
                deConversionData(History[RealTime]);
                isSaved = false;
            }
        }

        public void NewHistoryRec()
        {
            History.RemoveRange(RealTime+ 1, History.Count - RealTime - 1);
            SerilizeData hisBuff = new SerilizeData();
            conversionData(hisBuff);
            History.Add(hisBuff);
            RealTime++;
            isSaved = false;
        }

        private void trbScroll_Leave(object sender, EventArgs e)
        {
            trbScrol.Value = 5;
            previusValue = 5;
        }

        private void tSBSaveAsImage_Click(object sender, EventArgs e)
        {
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    var path = saveFileDialog1.FileName;
                    var image = new Bitmap(canvas.Height, canvas.Width);
                    canvas.DrawToBitmap(image, new Rectangle(0, 0, canvas.Width, canvas.Height));
                    image.Save(path, System.Drawing.Imaging.ImageFormat.Bmp);
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void выгрузитьВbmpToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    var path = saveFileDialog1.FileName;
                    var image = new Bitmap(canvas.Height, canvas.Width);
                    canvas.DrawToBitmap(image, new Rectangle(0, 0, canvas.Width, canvas.Height));
                    image.Save(path, System.Drawing.Imaging.ImageFormat.Bmp);
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
    }
}
